<?php 

/** Оценки
 *
 */
class dof_storage_guestbook extends dof_storage
{
    /**
     * @var dof_control
     */
    protected $dof;
    // **********************************************
    // Методы, предусмотренные интерфейсом plugin
    // **********************************************

    public function install()
    {
        if ( ! parent::install() )
        {
            return false;
        }
        // после установки плагина устанавливаем права
        return $this->dof->storage('acl')->save_roles($this->type(),$this->code(),$this->acldefault());
    }
    
    /** Метод, реализующий обновление плагина в системе
     * Создает или модифицирует существующие таблицы в БД
     * @param string $old_version - версия установленного в системе плагина
     * @return boolean
     * @access public
     */
    public function upgrade($oldversion)
    {
        global $CFG, $DB;
        require_once($CFG->libdir.'/ddllib.php');//методы для установки таблиц из xml
        $result = true;
        // Модификация базы данных через XMLDB
        /*if ($oldversion < 2012092600)
        {
            $dbman = $DB->get_manager();
            $oldtable = new xmldb_table('block_dof_s_gmessages');
            $dbman->rename_table($oldtable, 'block_dof_s_guestbook', true, true);
       }*/    
       // обновляем права доступа, если есть такая необходимость
       return ( $result AND $this->dof->storage('acl')->save_roles($this->type(),$this->code(),$this->acldefault()) );
    }
    
    /** Возвращает версию установленного плагина
     * @return string
     * @access public
     */
    public function version()
    {
        // Версия плагина (используется при определении обновления)
        return 2012092010;
    }
    
    /** Возвращает версии интерфейса Деканата,
     * с которыми этот плагин может работать
     * @return string
     * @access public
     */
    public function compat_dof()
    {
        return 'aquarium';
    }

    /** Возвращает версии стандарта плагина этого типа,
     * которым этот плагин соответствует
     * @return string
     * @access public
     */
    
    public function compat()
    {
        return 'paradusefish';
    }

    /** Возвращает тип плагина
     * @return string
     * @access public
     */
    public function type()
    {
        return 'storage';
    }
    
    /** Возвращает короткое имя плагина
     * Оно должно быть уникально среди плагинов этого типа
     * @return string
     * @access public
     */
    public function code()
    {
        return 'guestbook';
    }
    
    /** Возвращает список плагинов,
     * без которых этот плагин работать не может
     * @return array
     * @access public
     */
    public function need_plugins()
    {
        return array('storage'=>array('acl'=>2011040504));
    }
    
    /** Определить, возможна ли установка плагина в текущий момент
     * Эта функция одинакова абсолютно для всех плагинов и не содержит в себе каких-либо зависимостей
     * @TODO УДАЛИТЬ эту функцию при рефакторинге. Вместо нее использовать наследование
     * от класса dof_modlib_base_plugin
     * @see dof_modlib_base_plugin::is_setup_possible()
     *
     * @param int $oldversion[optional] - старая версия плагина в базе (если плагин обновляется)
     *                                    или 0 если плагин устанавливается
     *
     * @return bool
     *              true - если плагин можно устанавливать
     *              false - если плагин устанавливать нельзя
     */
    public function is_setup_possible($oldversion=0)
    {
        return dof_is_plugin_setup_possible($this, $oldversion);
    }
    
    /** Получить список плагинов, которые уже должны быть установлены в системе,
     * и без которых начать установку или обновление невозможно
     *
     * @param int $oldversion[optional] - старая версия плагина в базе (если плагин обновляется)
     *                                    или 0 если плагин устанавливается
     * @return array массив плагинов, необходимых для установки
     *      Формат: array('plugintype'=>array('plugincode' => YYYYMMDD00));
     */
    public function is_setup_possible_list($oldversion=0)
    {
        return array('storage'=>array('acl'=>2011040504));
    }
    /** Список обрабатываемых плагином событий
     * @return array - array(array('plugintype'=>..,'plugincode'=>..,'eventcode'=>..),...)
     * @access public
     */
    public function list_catch_events()
    {
        // Пока событий не обрабатываем
        return array(array('plugintype'=>'storage', 'plugincode'=>'guestbook', 'eventcode'=>'insertmessage'),
                array('plugintype' => 'storage', 'plugincode' => 'persons', 'eventcode' => 'newperson'));
        
        //return array();
    }
    /** Требуется ли запуск cron в плагине
     * @return bool
     * @access public
     */
    public function is_cron()
    {
        // Просим запускать крон не чаще раза в 15 минут
        return false;
    }

    /** Проверяет полномочия на совершение действий
     * @param string $do - идентификатор действия, которое должно быть совершено
     * @param int $id_obj - идентификатор экземпляра объекта,
     * по отношению к которому это действие должно быть применено
     * @param int $user_id - идентификатор пользователя, полномочия которого проверяются
     * @return bool true - можно выполнить указанное действие по отношению к выбранному объекту
     * false - доступ запрещен
     * @access public
     */
    public function is_access($do, $objid = NULL, $userid = NULL, $depid = null)
    {
        if ( $this->dof->is_access('datamanage') OR $this->dof->is_access('admin')
                OR $this->dof->is_access('manage') )
        {// манагеру можно все
            return true;
        }
        // получаем id пользователя в persons
        $personid = $this->dof->storage('persons')->get_by_moodleid_id($userid);
        // получаем все нужные параметры для функции проверки прав
        $acldata = $this->get_access_parametrs($do, $objid, $personid, $depid);
        // проверка
        if ( $this->acl_check_access_paramenrs($acldata) )
        {// право есть заканчиваем обработку
            return true;
        }
        return false;
    }

    /** Требует наличия полномочия на совершение действий
     * @param string $do - идентификатор действия, которое должно быть совершено
     * @param int $id_obj - идентификатор экземпляра объекта,
     * по отношению к которому это действие должно быть применено
     * @param int $user_id - идентификатор пользователя, полномочия которого проверяются
     * @return bool true - можно выполнить указанное действие по отношению к выбранному объекту
     * false - доступ запрещен
     * @access public
     */
    public function require_access($do, $objid = NULL, $userid = NULL, $depid = null)
    {
        // Используем функционал из $DOFFICE
        //return $this->dof->require_access($do, NULL, $userid);
        if ( ! $this->is_access($do, $objid, $userid, $depid) )
        {
            $notice = "{$this->code()}/{$do} (block/dof/{$this->type()}/{$this->code()}: {$do})";
            if ($objid)
            {
                $notice.=" id={$objid}";
            }
            $this->dof->print_error('nopermissions','',$notice);
            }
    }

        /** Обработать событие
         * @param string $gentype - тип модуля, сгенерировавшего событие
         * @param string $gencode - код модуля, сгенерировавшего событие
         * @param string $eventcode - код задания
         * @param int $intvar - дополнительный параметр
         * @param mixed $mixedvar - дополнительные параметры
         * @return bool - true в случае выполнения без ошибок
         * @access public
         */
        public function catch_event($gentype,$gencode,$eventcode,$intvar,$mixedvar)
        {
            if ( $gentype === 'storage' AND $gencode === 'guestbook' )
            {//обрабатываем события от справочника cstreamlink
                switch($eventcode)
                {
                    // при добавлении сообщения увеличиваем счетчик собщений
                    case 'insertmessage':
                        global $DB;
                        $msgcount = new stdClass();
                        $msgcount = $DB->get_record('block_dof_s_gb_counter', array('id' => 1));
                        $msgcount->msgcount = intval($msgcount->msgcount) + 1; 
                        $DB->update_record('block_dof_s_gb_counter', $msgcount);
                        break;
                    
                    case 'newperson':
                       return true;
                }
            }
            
            // Ничего не делаем, но отчитаемся об "успехе"
            return true;
        }
        /** Запустить обработку периодических процессов
         * @param int $loan - нагрузка (1 - только срочные, 2 - нормальный режим, 3 - ресурсоемкие операции)
         * @param int $messages - количество отображаемых сообщений (0 - не выводить,1 - статистика,
         *  2 - индикатор, 3 - детальная диагностика)
         * @return bool - true в случае выполнения без ошибок
         * @access public
         */
        public function cron($loan,$messages)
        {
            return true;
        }
        /** Обработать задание, отложенное ранее в связи с его длительностью
         * @param string $code - код задания
         * @param int $intvar - дополнительный параметр
         * @param mixed $mixedvar - дополнительные параметры
         * @return bool - true в случае выполнения без ошибок
         * @access public
         */
        public function todo($code,$intvar,$mixedvar)
        {
            return true;
        }
        /** Конструктор
         * @param dof_control $dof - объект с методами ядра деканата
         * @access public
         */
        public function __construct($dof)
        {
            // Сохраняем ссылку на DOF, чтоб вызывать его через $this->dof
            $this->dof = $dof;
        }

        /** Возвращает название таблицы без префикса (mdl_)
         * @return text
         * @access public
         */
        public function tablename()
        {
            // Имя таблицы, с которой работаем
            return 'block_dof_s_guestbook';
        }

        // **********************************************
        //       Методы для работы с полномочиями
        // **********************************************

        /** Получить список параметров для фунции has_hight()
         *
         * @return object - список параметров для фунции has_hight()
         * @param string $action - совершаемое действие
         * @param int $objectid - id объекта над которым совершается действие
         * @param int $personid
         */
        protected function get_access_parametrs($action, $objectid, $personid, $depid = null)
        {
            $result = new object();
            $result->plugintype   = $this->type();
            $result->plugincode   = $this->code();
            $result->code         = $action;
            $result->personid     = $personid;
            $result->departmentid = $depid;
            $result->objectid     = $objectid;

            return $result;
        }

        /** Проверить права через плагин acl.
         * Функция вынесена сюда, чтобы постоянно не писать длинный вызов и не перечислять все аргументы
         *
         * @return bool
         * @param object $acldata - объект с данными для функции storage/acl->has_right()
         */
        protected function acl_check_access_paramenrs($acldata)
        {
            return $this->dof->storage('acl')->
            has_right($acldata->plugintype, $acldata->plugincode, $acldata->code,
                    $acldata->personid, $acldata->departmentid, $acldata->objectid);
        }

        /** Возвращает стандартные полномочия доступа в плагине
         * @return array
         *  a[] = array( 'code'  => 'код полномочия',
         * 				 'roles' => array('student' ,'...');
         */
        public function acldefault()
        {
            $a = array();

            $a['view']     = array('roles'=>array('manager'));

            return $a;
        }

        // **********************************************
        //           Пользовательские   Методы
        // **********************************************
        
        
        // **********************************************
        //              Методы sql запросов
        // **********************************************
        
        /** Возвращает n последних сообщений
         * @return array or false		 
         */
        public function get_message_list() {
            
            global $DOF;
            
            $table = 'mdl_'.$this->tablename();
            $n = 12;
            
            $query = "  SELECT * FROM $table 
                ORDER BY date DESC
                LIMIT $n";

            $arrBuf = $DOF->storage($this->code())->get_records_sql($query);
             
            // преобразуем массив объектов в ассоциативный массив
            $arrBuf = (array)$arrBuf;
            foreach ($arrBuf as $value)
            {
                $arrResult[] = (array)$value;
            }
             
            if (!empty($arrResult)) 
            {
                return  $arrResult;
            }
            return false ;        
        }

        /** Возвращает сообщение п его id
         * 
         * @return array or fasle
         * @param int $id - id сообщения
         *
         */
        public function get_message_by_id($id) {
         
            global $DOF;
            
            if (intval($id) > 0)
            {
                $arrMsg = $DOF->storage('guestbook')->get_record(array('id' => $id));
                $arrCmt = $DOF->storage('gbcomments')->get_records(array('messageid' => $id));
                 
                $arrResult[] = (array)$arrMsg;
                
                foreach ($arrCmt as $value)
                {
                    $arrResult['COMMENTS'][] = (array)$value;
                }
                
                if (!empty($arrResult))
                {
                    return $arrResult;
                }    
            }
            
            return false;
        }
        
        /** Добавление комментария к сообщению
         *
         * @return bool
         * @param array $arrParam 
         *     => msgid - id сообщения
         *     => author - автор комментария 
         *     => text - текст коментария
         *     
         */    
        public function add_comment_to_message($arrParam) {

            if (intval($arrParam['msgid']) > 0 AND trim($arrParam['text']) != '' 
                    AND trim($arrParam['author']) != '')
            {
                foreach ($arrParam as $key => $value)
                {
                    $arrParam[$key] = htmlspecialchars($arrParam[$key], ENT_QUOTES);
                }
                
                global $DOF;
                
                // добавляем новый комментарий, достаем счетчик комментариев
                // из nтаблицы сообщений, инкрементим его, бросаем обратно в таблицу
                $record = new stdClass();
                $record->author = $arrParam['author'];
                $record->text = $arrParam['text'];
                $record->date = date("Y-m-d H:i:s");
                $record->messageid = intval($arrParam['msgid']);
                
                $insert = $DOF->storage('gbcomments')->insert($record);
                
                $count = $DOF->storage($this->code())->get_record(array('id' => $arrParam['msgid']), 'commentcnt');
                
                $record2 = new stdClass();
                $record2->id = intval($arrParam['msgid']);
                $record2->commentcnt = intval($count->commentcnt) + 1;
                $update = $DOF->storage('guestbook')->update($record2, $arrParam['msgid']);
                
                if ($insert AND $update)
                    return true;
                    
            }
            
            return false;
            
        }
        
        /** Изменение сообщения
         *
         * @return array or fasle
         * @param array $arrParam 
         *    => msgid - id сообщения
         *    => msgtext - текст сообщения
         */
        public function update_message($arrParam) {
            
            if (intval($arrParam['msgid']) > 0)
            {
                foreach ($arrParam as $key => $value)
                    $arrParam[$key] = htmlspecialchars($arrParam[$key], ENT_QUOTES);
                
                global $DOF;
                
                $record = new stdClass();
                $record->id = intval($arrParam['msgid']);
                $record->text = $arrParam['msgtext'];
                $update = $DOF->storage($this->code())->update($record, $arrParam['msgid']);
                
                if ($update)
                    return true;
            }
            
            return false;
            
        }
        
        /** Удаление сообщения
         *
         * @return bool
         * @param int $id - id сообщения
         *
         */
        public function delete_message($id) {
            
            if (intval($id) > 0)
            {
                global $DOF;
                
                $delmsg = $DOF->storage($this->code())->delete($id);
                
                $comlist = $DOF->storage('gbcomments')->get_records(array('messageid' => $id), 'id');
                
                foreach ($comlist as $value)
                {
                    $delcmt = $DOF->storage('gbcomments')->delete($value->id);
                }
                
                if ($delmsg)
                    return true;
            }
            
            return false;
        }
        
        /** Удаляет комментарий, снижает счетчик комментариев для сообщения 
         *
         * @return bool
         * @param array $arrParam
         *     => cmtid - id комментария
         *     => msgid - id сообщения
         */
        public function delete_comment($arrParam) {
            
            if (intval($arrParam['cmtid']) > 0)
            {
                global $DOF;
                
                $delete = $DOF->storage('gbcomments')->delete($arrParam['cmtid']);
                
                $count = $DOF->storage($this->code())->get_record(array('id' => $arrParam['msgid']), 'commentcnt');
                
                $record = new stdClass();
                $record->id = intval($arrParam['msgid']);
                $record->commentcnt = intval($count->commentcnt) - 1;
                $update = $DOF->storage($this->code())->update($record, $arrParam['msgid']);
                
                if ($delete && $update)
                    return true;
            }
            
            return false;
        }
        
        public function add_message_to_list($arrParam) {

            foreach ($arrParam as $key => $value)
            {
                $arrParam[$key] = htmlspecialchars($arrParam[$key], ENT_QUOTES);
            }
            
            $response = 'no';
            $targetid = 0;
            	
            // если айдишник сообщения для ответа - число больше нуля, это сообщение-ответ,
            // в противном случае id некорректен
            if (0 < intval($arrParam['msglist']))
            {
                $response = 'yes';
                $targetid = intval($arrParam['msglist']);
            }
            
            // если нет пустых полей, то добавить сообщение
            if (trim($arrParam['msgtitle']) != '' AND trim($arrParam['login']) != '' 
                    AND trim($arrParam['msgtext']) != '')
            {
                global $DOF;
                
                $record = new stdClass();
                $record->title = $arrParam['msgtitle'];
                $record->text = $arrParam['msgtext'];
                $record->author = $arrParam['login'];
                $record->date = date("Y-m-d H:i:s");
                $record->commentcnt = 0;
                $record->response = $response;
                $record->targetid = $targetid;
                $record->showcomment = 'no';
                
                $lastid = $DOF->storage('guestbook')->insert($record);
                
                if ($lastid)
                    return true;
            }
            
            return false;
        }
        // end class
    }

?>